package fxc.example;
import tech.tablesaw.api.DoubleColumn;
import tech.tablesaw.api.Table;
import tech.tablesaw.plotly.Plot;
import tech.tablesaw.plotly.components.*;
import tech.tablesaw.plotly.traces.BarTrace;
import tech.tablesaw.plotly.traces.HistogramTrace;
import java.util.concurrent.ThreadLocalRandom;
import java.util.Arrays;

public class DualAxisHistogram {

    public static void plotHistogramWithFrequencyAxis(double[] data, int numBins) {
        // 1. 准备数据
        DoubleColumn dataColumn = DoubleColumn.create("频数", data);
        Table table = Table.create("频数").addColumns(dataColumn);

        // 2. 创建主直方图轨迹（左侧轴）
        HistogramTrace histogramTrace = HistogramTrace.builder(table.nCol("频数"))
                .name("频数")
                .nBinsX(numBins)
                .opacity(0.7)
                .marker(Marker.builder()
                        .color("#1f77b4")
                        .build())
                .build();

        // 3. 计算频率数据（手动计算）
        BinStats binStats = calculateBinStats(data, numBins);

        double[] bcs= binStats.binCenters;
        Double[] bcsD = new Double[bcs.length];
        for (int i=0;i<bcs.length;i++)
            bcsD[i] = Double.valueOf(bcs[i]);

//        // 4. 创建频率轨迹（右侧轴）- 使用BarTrace代替
        BarTrace freqTrace = BarTrace.builder(bcsD, binStats.relativeFrequencies)
                .name("频率")
                .opacity(0.5)
                .marker(Marker.builder()
                        .color("#1f77b4")
                        .build())
                .yAxis("y2")
                .build();
//        HistogramTrace histogramTrace = HistogramTrace.builder(table.nCol("Data"))
//                .name("频数")
//                .nBinsX(numBins)
//                .opacity(0.7)
//                .marker(Marker.builder()
//                        .color("#1f77b4")
//                        .build())
//                .build();

        // 5. 创建布局，配置双Y轴
        Layout layout = Layout.builder()
                .title("蒙特卡洛模拟结果分布（双Y轴）")
                .xAxis(Axis.builder()
                        .title("结果值")
                        .build())
                .yAxis(Axis.builder()
                        .title("频数")
                        .side(Axis.Side.left)
                        .build())
                .yAxis2(Axis.builder()
                        .title("频率")
                        .side(Axis.Side.right)
//                        .overlaying(Axis.)
                        .showGrid(false)
                        .build())
//                .barmode(BarTrace.BarBuilder.class.)
                .width(900)
                .height(600)
                .showLegend(false)
                .build();

        // 6. 显示图表
        Plot.show(new Figure(layout, Config.builder().displayModeBar(false).responsive(true).build(), histogramTrace, freqTrace));
//            Plot.show(new Figure(layout, histogramTrace));
        }

    // 辅助类：存储分箱统计结果
    private static class BinStats {
        double[] binCenters;
        double[] relativeFrequencies;

        BinStats(double[] binCenters, double[] relativeFrequencies) {
            this.binCenters = binCenters;
            this.relativeFrequencies = relativeFrequencies;
        }
    }

    // 手动计算分箱统计信息
    private static BinStats calculateBinStats(double[] data, int numBins) {
        // 计算最小最大值
        double min = Arrays.stream(data).min().orElse(0);
        double max = Arrays.stream(data).max().orElse(1);

        // 计算箱宽和边界
        double binWidth = (max - min) / numBins;
        double[] binEdges = new double[numBins + 1];
        for (int i = 0; i <= numBins; i++) {
            binEdges[i] = min + i * binWidth;
        }

        // 计算每个箱的计数
        int[] counts = new int[numBins];
        for (double value : data) {
            int binIndex = (int) ((value - min) / binWidth);
            if (binIndex >= numBins) binIndex = numBins - 1;
            counts[binIndex]++;
        }

        // 计算箱中心和相对频率
        double[] binCenters = new double[numBins];
        double[] relativeFrequencies = new double[numBins];
        double total = data.length;

        for (int i = 0; i < numBins; i++) {
            binCenters[i] = binEdges[i] + binWidth / 2;
            relativeFrequencies[i] = counts[i] / total;
        }

        return new BinStats(binCenters, relativeFrequencies);
    }

    public static void main(String[] args) {
        // 生成示例数据
        double[] simulationData = new double[1000];
        for (int i = 0; i < simulationData.length; i++) {
            simulationData[i] = ThreadLocalRandom.current().nextGaussian() * 10 + 50;
        }

        // 绘制带频率轴的直方图
        plotHistogramWithFrequencyAxis(simulationData, 30);
    }
}